<template>
  <div class="home">
    <p>a:{{ a }}</p>
    <p>b:{{ b }}</p>

    <div><button type="button" @click="setA">setA</button></div>
    <div><button type="button" @click="setB">setB</button></div>
    <div><button type="button" @click="clearFn">stop</button></div>
  </div>
</template>

<script>
import { reactive, toRefs, watch, ref, watchEffect } from 'vue'

export default {
  name: 'HomeView',
  data() {
    return {
      myName: 'wenqingwu'
    }
  },
  mounted() {},
  // 组合式API：
  setup() {
    let age = ref(0)
    let name = ref('张三丰')
    let data = reactive({
      a: 1,
      b: 2,
      json: { c: 1 },
      setA: () => {
        data.a = 2000
      },
      setB: () => {
        data.b = 30000
        age.value = 100
        name.value = '小蚊子'
      }
    })

    // watch(参数1，参数2) ：
    // 参数1：应该使用一个回调函数，并返回一个依赖的ref对象
    // 参数2： 依赖改变时，执行的回调函数。函数有2个参数，参数1表示改变后的值，参数2表示改变前的值。
    // 参数3： 改变参数2的callback的执行时机。
    //支持以下这些选项：

    // immediate：在侦听器创建时立即触发回调。第一次调用时旧值是 undefined。
    // deep：如果源是对象，强制深度遍历，以便在深层级变更时触发回调。{a:{b:{c: {title:"xx"}},}}
    // flush：调整回调函数的刷新时机。
    // onTrack / onTrigger：调试侦听器的依赖。

    //1  普通的ref变量的依赖写法：
    watch(age, (newV, oldV) => {
      console.log('age变量改变前', oldV, '改变后的值：', newV)
    })
    // watch(),返回一个函数。

    const clearFn = watch(
      [name],

      (newV, oldV) => {
        console.log('name变量改变前', oldV, '改变后的值：', newV)
        //当执行了watch()返回的函数时，监听器就失效了。
      },
      {
        // immediate: true
        // flush: true
        flush: 'sync'
      }
    )

    //2 reactive()对象的属性的依赖的写法：
    // 只有一个依赖项的写法：
    // watch(
    //   () => data.a,
    //   (newV, oldV) => {
    //     console.log('变量改变前', oldV, '改变后的值：', newV)
    //   }
    // )

    // 多个依赖项的写法：
    watch([() => data.a, () => data.b], ([newVa, newVb], [oldVa, oldVb]) => {
      console.log('data.a变量改变前', oldVa, '改变后的值：', newVa)
      console.log('data.b变量改变前', oldVb, '改变后的值：', newVb)
    })

    watchEffect(() => {
      console.log('watchEffect:;;;;;;', data.a) // 自动判断监听watchEffect()的回调函数里面使用的变量。
      // onCleanup('dd') // 清除异步的一部分业务逻辑的执行
    })
    return {
      ...toRefs(data),
      clearFn
    }
  }
}
</script>
